home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / vprof / vprof.c
C/C++ Source or Header  |  1999-01-01  |  4KB  |  162 lines

  1. /*
  2.  * vprof
  3.  *
  4.  * vbcc profiler. Displays the contents of "mon.out" files.
  5.  * (C)1998 by Frank Wille <frank@phoenix.owl.de>
  6.  *
  7.  * vprof is freeware and part of the portable and retargetable ANSI C
  8.  * compiler vbcc, copyright (c) 1995-98 by Volker Barthelmann.
  9.  * vprof may be freely redistributed as long as no modifications are
  10.  * made and nothing is charged for it. Non-commercial usage is allowed
  11.  * without any restrictions.
  12.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  13.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  14.  *
  15.  * History:
  16.  * V0.1   28-Aug-98
  17.  *        File created.
  18.  *
  19.  */
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. #define VERSION 0
  26. #define REVISION 1
  27. #define PLEVEL 0
  28. #define DEFAULTNAME "mon.out"
  29.  
  30. struct profdata {
  31.   char *funcname;
  32.   unsigned long ncalls;
  33.   unsigned long tottime;
  34. };
  35.  
  36.  
  37.  
  38. static void show(struct profdata *pd,int n)
  39. /* write profdata records to stdout */
  40. {
  41.   printf("  %%         total                  total        function name\n"
  42.          " time      seconds     calls      ms/call\n");
  43.   while (n--) {
  44.     printf(" n.a.   %9.3f %10lu    %9.3f       %s\n",
  45.            (double)pd->tottime/1000000.0,
  46.            pd->ncalls,
  47.            ((double)pd->tottime/(double)pd->ncalls)/1000.0,
  48.            pd->funcname);
  49.     pd++;
  50.   }
  51. }
  52.  
  53.  
  54. static int cmp_total(const void *pd1,const void *pd2)
  55. {
  56.   return ((int)(((struct profdata *)pd2)->tottime -
  57.           ((struct profdata *)pd1)->tottime));
  58. }
  59.  
  60.  
  61. static void show_total(struct profdata *pd,int n)
  62. /* show profiling data, sorted according to the total time */
  63. /* spent in each function */
  64. {
  65.   qsort(pd,n,sizeof(struct profdata),cmp_total);
  66.   show(pd,n);
  67. }
  68.  
  69.  
  70. static char *skipname(char *p)
  71. /* skip name and alignment bytes and return pointer to profile data */
  72. {
  73.   int n = strlen(p)+1;
  74.  
  75.   p += n;
  76.   if (n &= 3)
  77.     p += 4-n;
  78.   return (p);
  79. }
  80.  
  81.  
  82. main(int argc,char *argv[])
  83. {
  84.   char *mname;
  85.   FILE *fp;
  86.   long size,len;
  87.   char *buf,*p;
  88.   int i,nrecs = 0;
  89.   struct profdata *pdata,*pd;
  90.  
  91.   if (argc >= 2) {
  92.     if (*argv[1]=='-' || *argv[1]=='?') {
  93.       printf("%s V%d.%d%c (c)1998 by Frank Wille\n"
  94.              "Usage:\n  %s [mon.out]\n",argv[0],
  95.              VERSION,REVISION,PLEVEL?('a'+PLEVEL-1):' ',argv[0]);
  96.       exit(1);
  97.     }
  98.     else
  99.       mname = argv[1];
  100.   }
  101.   else
  102.     mname = DEFAULTNAME;
  103.  
  104.   if (fp = fopen(mname,"r")) {
  105.     /* determine file size */
  106.     fseek(fp,0,SEEK_END);
  107.     size = ftell(fp);
  108.     fseek(fp,0,SEEK_SET);
  109.     if (size < 0) {
  110.       fclose(fp);
  111.       fprintf(stderr,"%s: Seek error on %s!\n",argv[0],mname);
  112.       exit(EXIT_FAILURE);
  113.     }
  114.  
  115.     /* allocate buffer and read file */
  116.     if (!(buf = malloc(size))) {
  117.       fclose(fp);
  118.       fprintf(stderr,"%s: Not enough memory!\n",argv[0]);
  119.       exit(EXIT_FAILURE);
  120.     }
  121.     if (fread(buf,1,size,fp) != size) {
  122.       fclose(fp);
  123.       fprintf(stderr,"%s: %s had a read error!\n",argv[0],mname);
  124.       exit(EXIT_FAILURE);
  125.     }
  126.     fclose(fp);
  127.  
  128.     /* count number of entries in mon.out and allocate profdata array */
  129.     p = buf;
  130.     while (p < buf+size) {
  131.       nrecs++;
  132.       p = skipname(p) + 2*sizeof(unsigned long);
  133.     }
  134.     if (p!=buf+size || nrecs==0) {
  135.       fprintf(stderr,"%s: %s: Corrupted file format.\n",argv[0],mname);
  136.       exit(EXIT_FAILURE);
  137.     }
  138.     if (!(pdata = malloc(nrecs * sizeof(struct profdata)))) {
  139.       fprintf(stderr,"%s: Not enough memory!\n",argv[0]);
  140.       exit(EXIT_FAILURE);
  141.     }
  142.  
  143.     /* fill profdata array */
  144.     for (i=0,p=buf,pd=pdata; i<nrecs; i++,pd++) {
  145.       pd->funcname = p;
  146.       p = skipname(p);
  147.       pd->ncalls = *(unsigned long *)p;
  148.       pd->tottime = *(unsigned long *)(p+sizeof(unsigned long));
  149.       p += 2*sizeof(unsigned long);
  150.     }
  151.  
  152.     /* display */
  153.     show_total(pdata,nrecs);
  154.   }
  155.   else {
  156.     fprintf(stderr,"%s: Can't open %s.\n",argv[0],mname);
  157.     exit(EXIT_FAILURE);
  158.   }
  159.  
  160.   exit(0);
  161. }
  162.